package com.hjx.server;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * 服务器，用于接收http请求
 * Created by houjinxin on 2017/3/8.
 */
public class HttpServer {

    private static final Logger logger = LoggerFactory.getLogger(HttpServer.class);

    /**
     * web服务器根目录，存储静态资源，供外部访问
     */
    public static final String WEB_ROOT = System.getProperty("user.dir") + File.separator + "webroot";

    /**
     * shutdown标志
     */
    public static boolean shutdown = false;

    /**
     * shutdown请求url
     */
    public static final String SHUTDOWN_COMMAND = "/shutdown";

    /**
     * 等待请求接入
     */
    public void await() {
        ServerSocket serverSocket = null;
        int port = 8080;
        try {
            //创建服务端socket 指定IP和端口号，并请求队列最大值为1（backlog）
            serverSocket = new ServerSocket(port, 1, InetAddress.getByName("127.0.0.1"));
            logger.info("serverSocket has been created successfully, ip:{},port:{}", serverSocket.getInetAddress().toString(), serverSocket.getLocalPort());
        } catch (IOException e) {
            logger.error("serverSocket create failed, program exit!");
            e.printStackTrace();
            //服务端socket建立失败，退出
            System.exit(1);
        }

        while(!shutdown){
            Socket socket = null;
            InputStream in = null;
            OutputStream out = null;

            try {
                //TODO:坑二，一个请求 serverSocket能接收两次，第二次报空指针异常
                //该方法在没有接收到请求时一直阻塞
                socket = serverSocket.accept();
                in = socket.getInputStream(); //请求输入
                out = socket.getOutputStream(); //响应输出

                //请求对象解析输入流, 获取请求行、请求头、请求体
                Request request = new Request(in);
                //解析请求，这里只获取url
                request.parse();

                //响应对象负责输出
                Response response = new Response(out);
                //响应需要用到请求中的信息，如请求的url等
                response.setRequest(request);
                response.render();

                //关闭socket
                socket.close();
                //判断是否要关闭
                shutdown = SHUTDOWN_COMMAND.equals(request.getUri());
            } catch (IOException e) {
                logger.error("client request failed!", e);
                e.printStackTrace();
                //此处异常表示一个请求异常，不需要终止服务器
            }
        }
    }
}
